
package com.jf.cloud.biz.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.jf.cloud.api.multishop.bo.ShopSimpleBO;
import com.jf.cloud.api.multishop.feign.ShopDetailFeignClient;
import com.jf.cloud.biz.dto.NotifyLogDTO;
import com.jf.cloud.biz.mapper.NotifyLogMapper;
import com.jf.cloud.biz.model.NotifyLog;
import com.jf.cloud.biz.service.NotifyLogService;
import com.jf.cloud.biz.vo.NotifyLogVO;
import com.jf.cloud.common.constant.StatusEnum;
import com.jf.cloud.common.database.dto.PageDTO;
import com.jf.cloud.common.database.util.PageUtil;
import com.jf.cloud.common.database.vo.PageVO;
import com.jf.cloud.common.exception.LuckException;
import com.jf.cloud.common.response.ServerResponseEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 *
 *
 * @author zz
 * @date 2021-01-16 15:01:14
 */
@Service
public class NotifyLogServiceImpl implements NotifyLogService {

    @Autowired
    private NotifyLogMapper notifyLogMapper;
    @Autowired
    private ShopDetailFeignClient shopDetailFeignClient;

    @Override
    public PageVO<NotifyLogVO> pageBySendTypeAndRemindType(PageDTO page, Long userId, Integer msgType, Integer status) {
        // 不要用已读未读及更新时间作为排序的条件，查询消息列表时未读消息会更新为已读消息，此时消息读取状态发生、更新时间发生改变
        return PageUtil.doPage(page, () -> notifyLogMapper.listBySendTypeAndRemindType(userId,msgType,status));
    }

    @Override
    public PageVO<NotifyLogVO> pageShopNotifyLogByParam(PageDTO page, NotifyLogDTO notifyLogDTO) {
        return PageUtil.doPage(page, () -> notifyLogMapper.list(notifyLogDTO));
    }

    @Override
    public void updateBatchById(List<NotifyLogVO> notifyLogList) {
        notifyLogMapper.updateBatchById(notifyLogList);
    }

    @Override
    public int countUnreadBySendTypeAndRemindType(Long userId, Integer msgType) {
        List<NotifyLogVO> notifyLogList = notifyLogMapper.listBySendTypeAndRemindType(userId, msgType, StatusEnum.DISABLE.value());

        return CollectionUtil.isEmpty(notifyLogList) ? 0 : notifyLogList.size();
    }

    @Override
    public void saveBatch(List<NotifyLog> notifyLogs) {
        notifyLogMapper.saveBatch(notifyLogs);
    }

    @Override
    public PageVO<NotifyLogVO> page(PageDTO pageDTO, NotifyLogDTO notifyLogDTO) {
        PageVO<NotifyLogVO> page = PageUtil.doPage(pageDTO, () -> notifyLogMapper.list(notifyLogDTO));
        if (CollUtil.isEmpty(page.getList())) {
            return page;
        }
        List<NotifyLogVO> notifyLogList = page.getList();
        ShopSimpleBO shopSimpleBO = new ShopSimpleBO();
        shopSimpleBO.setSeq(1);
        shopSimpleBO.setShopIds(notifyLogList.stream().map(NotifyLogVO::getShopId).collect(Collectors.toList()));
        ServerResponseEntity<List<ShopSimpleBO>> listServerResponseEntity = shopDetailFeignClient.listSimple(shopSimpleBO);
        if (listServerResponseEntity.isFail()) {
            throw new LuckException(listServerResponseEntity.getMsg());
        }
        List<ShopSimpleBO> shopSimpleList = listServerResponseEntity.getData();
        if (CollUtil.isEmpty(shopSimpleList)) {
            return page;
        }
        for (NotifyLogVO notifyLog : notifyLogList) {
            ShopSimpleBO shopSimple = this.getShopInfo(shopSimpleList, notifyLog.getShopId());
            if (Objects.nonNull(shopSimple)) {
                notifyLog.setShopName(shopSimple.getShopName());
            }
        }
        return page;
    }

    @Override
    public int countNotifyByConditions(Long orderId, Integer level, Long userId, Integer sendType) {
        return notifyLogMapper.countNotifyByConditions(orderId, level, userId, sendType);
    }

    private ShopSimpleBO getShopInfo(List<ShopSimpleBO> shopSimpleList, Long shopId) {
        if (CollUtil.isEmpty(shopSimpleList) || Objects.isNull(shopId)) {
            return null;
        }
        int leftIndex = 0, rightIndex = shopSimpleList.size() - 1, midIndex;
        while (leftIndex <= rightIndex) {
            midIndex = leftIndex + ((rightIndex - leftIndex) >>> 1);
            ShopSimpleBO shopSimpleBO = shopSimpleList.get(midIndex);
            if (Objects.equals(shopSimpleBO.getShopId(), shopId)) {
                return shopSimpleBO;
            }
            if (shopSimpleBO.getShopId() < shopId) {
                leftIndex = midIndex + 1;
            } else {
                rightIndex = midIndex - 1;
            }
        }
        return null;
    }

    @Override
    public void updateStatus(Long id) {
        notifyLogMapper.updateStatus(id);
    }

    @Override
    public NotifyLogVO getByLogId(Long logId) {
        return notifyLogMapper.getByLogId(logId);
    }

    @Override
    public void isReadByIds(List<Long> logIds) {
        notifyLogMapper.isReadByIds(logIds);
    }

    @Override
    public void isReadByShopId(Long shopId) {
        notifyLogMapper.isReadByShopId(shopId);
    }
}
